package jssia.database.mysql.columns;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;


public class TimestampColumn extends Column {

    private static final Calendar MIN_TIMESTAMP = Calendar.getInstance();
    private static final Calendar MAX_TIMESTAMP = Calendar.getInstance();
    private static final long MIN_TIMESTAMP_MILLIS;
    private static final long MAX_TIMESTAMP_MILLIS;

    static {
        MIN_TIMESTAMP.set(1970, Calendar.JANUARY, 1, 0, 0, 1);
        MAX_TIMESTAMP.set(2038, Calendar.JANUARY, 19, 3, 14, 07);
        MIN_TIMESTAMP_MILLIS = MIN_TIMESTAMP.getTimeInMillis();
        MAX_TIMESTAMP_MILLIS = MAX_TIMESTAMP.getTimeInMillis();
    }

    public Timestamp get(ResultSet rs) throws SQLException {
        return rs.getTimestamp(fullyQualifiedName);
    }

    public void set(PreparedStatement ps, int index, Calendar calender) throws SQLException {
        if (calender.before(MIN_TIMESTAMP) || calender.after(MAX_TIMESTAMP))
            throw new IllegalArgumentException("Invalid time of " + calender.getTime() + ", must be between " + MIN_TIMESTAMP.getTime() + " and " + MAX_TIMESTAMP.getTime());
        ps.setTimestamp(index, new Timestamp(calender.getTimeInMillis()), calender);
    }

    public void set(PreparedStatement ps, int index, Date date) throws SQLException {
        set(ps, index, date.getTime());
    }

    public void set(PreparedStatement ps, int index, Timestamp timestamp) throws SQLException {
        long millis = timestamp.getTime();
        if (millis < MIN_TIMESTAMP_MILLIS || millis > MAX_TIMESTAMP_MILLIS)
            throw new IllegalArgumentException("Invalid time of " + timestamp + ", must be between " + MIN_TIMESTAMP_MILLIS + " and " + MAX_TIMESTAMP_MILLIS);
        ps.setTimestamp(index, timestamp);
    }

    public void set(PreparedStatement ps, int index, long millis) throws SQLException {
        if (millis < MIN_TIMESTAMP_MILLIS || millis > MAX_TIMESTAMP_MILLIS)
            throw new IllegalArgumentException("Invalid time of " + new Date(millis) + ", must be between " + MIN_TIMESTAMP_MILLIS + " and " + MAX_TIMESTAMP_MILLIS);
        ps.setTimestamp(index, new Timestamp(millis));
    }
}
